package contact.view.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletContext;

import contact.controller.QueryManager;
import contact.controller.VerticalManager;
import contact.controller.VerticalResultsManager;

import model.db.Query;
import model.db.Vertical;
import model.db.VerticalResult;
import util.hashing.Sorting;
import util.math.RandomElement;

public class SurveyLogic {

	private static final String QUERIES_ATT = "QUERIES_ATT";
	

	//image verticals

	public static final String[] image_verticals={"google_images", "google_drawing",
		"google_clipart", "google_worksheets"};


	public static final String START_TIME= "START_VERTICAL";
	
	public static final String END_TIME= "END_VERTICAL";
	
	public static final String IMAGE_VERTICAL= "IMAGE_VERTICAL";
	
	
	public static final String ASSESMENTS= "IMAGE_VERTICAL";
	
	
	public static final boolean  AGAINTS_GOOGLE=true;

	public static final String WEB_VERTICAL= "WEB_VERTICAL";

	
	public static final String ACTION_LOGIN="login";
	
	public static final String ACTION_SURVEY="survey";
	
	public static final String SESSION_QUERY = "current_query";
	public static final String LOGIN = "login";
	public static final String LOGIN_ACTIVE = "active";
	public static final String USER = "user";
	public static final String VERTICALS_INFO = "VERTICALS_INFO";
//	public static final String SESSION_VERTICAL_RESULTS = "SESSION_VRESULTS";
	
	public static final String SESSION_VERTICAL_HASH = "SESSION_HASHRESULTS";
	
	
	
	
	public static final String LEFT_VERTICAL = "LEFT_VRESULTS";
	public static final String RIGHT_VERTICAL = "RIGHT_VRESULTS";
	
	public static final String SESSION_LEFT_RESULTS = "SESSION_LRESULTS";
	
	
	public static final String SESSION_RIGHT_RESULTS = "SESSION_RRESULTS";
	
	//public static final String SESSION_GOOGLE_RESULTS = "SESSION_GRESULTS";
	public static final String SESSION_SEQUENCE = "SESSION_SEQUENCE";
	
	
	
	public static final String QUERIES_HASH = "QUERIES_HASH";
	
	public static final long GOOGLE_ID= 61l;
	
	public static final int MAX_RANK=4;
	
	
	
	public static  Query getNextQuery(ServletContext servletContext, QueryManager queryManager, Map<String, Object> session ){
		
		
		updateContextQueries(servletContext,queryManager);
		
		Hashtable<Long, Query> queries = (Hashtable<Long, Query>) servletContext.getAttribute(QUERIES_ATT);		
		
		Hashtable<Long, Integer> query_counts = (Hashtable<Long, Integer>) servletContext.getAttribute(QUERIES_HASH);		
		
		
		Iterator<Entry<Long, Integer>> sorted_queries = Sorting.sortHashQueries(query_counts, false);
		
		
		ArrayList<Long> sorted = extractCandidateQueries(sorted_queries);
		
		//printArrayList(sorted,"Printing array list of randomized query ids");
		
		
		Long id_next = (Long) RandomElement.getRandomElement(sorted);
		
		
		
		return queries.get(id_next);
		
		
	}
	
	
	
	
	



	private static void printArrayList(ArrayList<Long> sorted, String message) {
		// TODO Auto-generated method stub
		System.out.println(message);
		for(int i=0; i < sorted.size(); i++){
			System.out.println(sorted.get(i));
			
		}
		
		
	}




	public static  void loadVerticalInfo(ServletContext servletContext, VerticalManager verticalManager ){
		
		
		if(servletContext.getAttribute(SurveyLogic.VERTICALS_INFO)!=null) return;
		
		Hashtable<Long,Vertical> h = new Hashtable<Long,Vertical>();
		
		
		
		
		
		List<Vertical> lista = verticalManager.list();
		
		
		for(int i =0; i<lista.size(); i++){
			
	
			Vertical v= lista.get(i);
			
			h.put(v.getId(), v);
		}
		
		servletContext.setAttribute(VERTICALS_INFO, h);
		
	}
	
	public static void printVerticalInfo(ServletContext servletContext){
		
		Hashtable<Long,Vertical> h= (Hashtable<Long, Vertical>) servletContext.getAttribute(VERTICALS_INFO);
		
		Enumeration<Long> keys = h.keys();
		System.out.println("Printing vertical info-------");
		while(keys.hasMoreElements()){
			
			Long l = keys.nextElement();
			System.out.println(l + "\t"+ h.get(l).getName() + "\t"+h.get(l).getDescription());
		}
	}
	
	
	public static String classifyResultType(Vertical v) {

		for (int i = 0; i < image_verticals.length; i++) {

			if (image_verticals[i].equals(v.getCode())) {

				return IMAGE_VERTICAL;
			}
		}

		return WEB_VERTICAL;

	}
	
	public static  void assignCurrentVerticalDescriptions(ServletContext servletContext, Map<String, Object> session, List<VerticalResult> current_results2, List<VerticalResult> google_results2){
		
		Hashtable<Long,Vertical> info = (Hashtable<Long, Vertical>) servletContext.getAttribute(VERTICALS_INFO);
	
		System.out.println("Inside assignmet current vertical descriptions");
		System.out.println("Size: current results 2  "  + current_results2.size());
		
		if(current_results2.size()>0){
			VerticalResult result = current_results2.get(0);
			
			System.out.println(info.containsKey(result.getVertical_id())+ " \t contains key" + result.getVertical_id());
			Vertical v= info.get(result.getVertical_id());
			System.out.println("Adding in left vertical: "+ v.getCode());
			session.put(LEFT_VERTICAL, v);
			
			
		}
		
		System.out.println("Size: google results 2  "  +google_results2.size());
		
		
		if(google_results2.size()>0)
		{
			VerticalResult result = google_results2.get(0);
			
			Vertical v= info.get(result.getVertical_id());
			
			System.out.println("Adding in right vertical: "+ v.getCode());
			session.put(RIGHT_VERTICAL, v);
			
		}
		
		
		
	}
	public static Vertical getVertical(ServletContext servletContext, long id ){
		
		
		Vertical v= null;
	
		return ((Hashtable<Long,Vertical>)servletContext.getAttribute(VERTICALS_INFO)).get(id);
	
	}
	
	public static void incrementQueryCount(ServletContext servletContext, long id){
		
		Hashtable<Long, Integer> query_counts = (Hashtable<Long, Integer>) servletContext.getAttribute(QUERIES_HASH);
	
		query_counts.put(id, query_counts.get(id)+1);
		
	}
		
	private static void updateContextQueries(ServletContext servletContext, QueryManager queryManager) {

		Object queries_tmp = servletContext.getAttribute(QUERIES_ATT);

		Hashtable<Long, Integer> query_counts = new Hashtable<Long, Integer>();
		Hashtable<Long, Query> queries = new Hashtable<Long, Query>();
		if (queries_tmp == null) {

			List<Query> list_queries = queryManager.list();

			for (int i = 0; i < list_queries.size(); i++) {

				Query current = list_queries.get(i);

				queries.put(current.getId(), current);
				query_counts.put(current.getId(), 0);

			}

			servletContext.setAttribute(QUERIES_ATT, queries);
			servletContext.setAttribute(QUERIES_HASH, query_counts);

		}

	}
	
	
	private static ArrayList<Long> extractCandidateQueries(Iterator<Entry<Long, Integer>> e){
		ArrayList<Long> ids= new ArrayList<Long>();
		
		int min=1000000;
		while(e.hasNext()){
			
			
			Entry<Long, Integer> entry = e.next();
			int value = entry.getValue();
		//	System.out.println("Extracting candidates: " + entry.getKey() + "\t"+ entry.getValue()  + "\t" + min);
			if(value<=min){
				
				min= value;
			    ids.add(entry.getKey());
			}
		
		}
		
		
		return ids;
		
		
	}
	
	
	public static void printQueryCounts(ServletContext servletContext){
		
		Hashtable<Long, Integer> query_counts = (Hashtable<Long, Integer>) servletContext.getAttribute(QUERIES_HASH);		
		
		System.out.println("Printing query counts ");
		Enumeration<Long> keys = query_counts.keys();
		
		System.out.println("Printing queries");
		while(keys.hasMoreElements()){
			Long id= keys.nextElement();
			System.out.println(id + "\t"+ query_counts.get(id));
		}
		
	}
	
	
	public static void printQueryList(ServletContext servletContext){
	
		Hashtable<Long, Query> queries = (Hashtable<Long, Query>) servletContext.getAttribute(QUERIES_ATT);		
		
		Enumeration<Long> keys = queries.keys();
		
		System.out.println("Printing queries");
		while(keys.hasMoreElements()){
			
			
			Long id= keys.nextElement();
			Query q = queries.get(id);
			System.out.println(id + "\t"+ q.getQuery());
			
		}
		
	}
	
	
	public static void cleanSessionData(Map<String, Object> session){
		
		
		ArrayList<VerticalResult>current= (ArrayList<VerticalResult>)session.get(SESSION_LEFT_RESULTS);
		
		if(current!=null){
		
			current.clear();
			current=null;
			}
		
		
		ArrayList<VerticalResult> google = (ArrayList<VerticalResult>)session.get(SESSION_RIGHT_RESULTS);
		
		if (google!=null){
			google.clear();
			google=null;
		}
		
		 Hashtable<Long, ArrayList<VerticalResult>> vertical= ( Hashtable<Long, ArrayList<VerticalResult>>)session.get(SESSION_VERTICAL_HASH);
		
		if(vertical!=null){
		vertical.clear();
		vertical=null;
		}
		
		session.remove(LEFT_VERTICAL);
		session.remove(RIGHT_VERTICAL);
		session.remove(SESSION_LEFT_RESULTS);
		session.remove(SESSION_VERTICAL_HASH);
		session.remove(SESSION_RIGHT_RESULTS);
		session.remove(SESSION_QUERY);
		
	}
	
	
	public static void printLeftWebResult(Map<String, Object> session){
	
		System.out.println("Printing  current web results");
		
		
		if(session.containsKey(SESSION_VERTICAL_HASH)){
			 Hashtable<Long, ArrayList<VerticalResult>> organized_list= ( Hashtable<Long, ArrayList<VerticalResult>>) session.get(SESSION_VERTICAL_HASH);	
				 	
			 
			 
			 Enumeration<Long> keys = organized_list.keys();
			 
			 while(keys.hasMoreElements()){
				 
				 
				Long key = keys.nextElement();
				ArrayList<VerticalResult> vertical_results = organized_list.get(key);
				for(int i=0; i< vertical_results.size(); i++){
					
					System.out.println("\t"+vertical_results.get(i).getId() + "\t" + vertical_results.get(i).getVertical_id() + "\t"+vertical_results.get(i).getTitle ()+ "\t"+ vertical_results.get(i).getRank());
					
					
				}
				 
			 }
		
		
		}
		
		
		
		 System.out.println("Printing current list of left results");
			
		if(session.containsKey(SESSION_LEFT_RESULTS)){
		 ArrayList<VerticalResult> organized_list= (ArrayList<VerticalResult>) session.get(SESSION_LEFT_RESULTS);	
		
		 
		 for(int i =0; i<organized_list.size(); i++){
		 
			 VerticalResult temp = organized_list.get(i);
			 System.out.println("\t"+ temp.getId() + "\t"+ temp.getVertical_id()+"\t"+temp.getTitle() + "\t"+ temp.getRank());
			
		 }
		 
		}
		
		 System.out.println("Printing current list of  right results");
			
			if(session.containsKey(SESSION_RIGHT_RESULTS)){
			 ArrayList<VerticalResult> organized_list= (ArrayList<VerticalResult>) session.get(SESSION_RIGHT_RESULTS);	
			
			 
			 for(int i =0; i<organized_list.size(); i++){
				 
				 
				 VerticalResult temp = organized_list.get(i);
				 System.out.println("\t"+ temp.getId() + "\t"+ temp.getVertical_id()+"\t"+temp.getTitle() + "\t"+ temp.getRank());
				 
				
			 }
			 
			}
		
		
		 
	}
	
	
	
	/**
	 * check user session for current list of vertical results
	 * 
	 * if it is empty load results given query_id
	 * 
	 * 
	 * @param query_id
	 * @return
	 */
	public static void getNextVerticalResults(long query_id, VerticalResultsManager verticalResultsManager, Map<String, Object> session, boolean againtsGoogle){
		
		
		Date start_time=null;
		
		if(session.containsKey(SESSION_VERTICAL_HASH)){
			
			
			 Hashtable<Long, ArrayList<VerticalResult>> organized= (Hashtable<Long, ArrayList<VerticalResult>>)session.get(SESSION_VERTICAL_HASH);
			
			 ArrayList<long[]> sequence = (ArrayList<long[]>) session.get(SESSION_SEQUENCE);
			 	
			 
			 System.out.println("It already exists!");
			 
			 if(sequence.size()<1){
				 
				 return;
			 }
		
			 long[] vertical_ids = sequence.get(0);
	
			 ArrayList<VerticalResult> left_results = organized.get(vertical_ids[0]);
			 ArrayList<VerticalResult> right_results = organized.get(vertical_ids[1]);
				
			 session.put(SESSION_LEFT_RESULTS, left_results);
			
			 session.put(SESSION_RIGHT_RESULTS, right_results);
				
			 start_time = new Date();
			 
			 session.put(START_TIME, start_time);			 
		}else{
			
			 List<VerticalResult> results = verticalResultsManager.getVerticalResults(query_id, MAX_RANK);
			
			 System.out.println("Results row");
			
			 for(int i=0 ; i<results.size(); i++){
				 
				 System.out.println(results.get(i).getId()+ "\t"+ results.get(i).getVertical_id()+ "\t"+ results.get(i).getTitle());
				 
			 }
			 
			 Hashtable<Long, ArrayList<VerticalResult>> organized = verticalResultsManager.getVerticalResultsOrganized(results);

			 
			 ArrayList<ArrayList<VerticalResult>> organized_list = verticalResultsManager.toList(organized);
			   
			 Comparissons compa = new Comparissons(againtsGoogle, organized_list,organized);
				
			 
			 
			 if(compa.sequence.size()>0){
				 
				 
				 session.put(SESSION_VERTICAL_HASH,organized);	
				 session.put(SESSION_SEQUENCE,compa.sequence);	
				  	
				 long vertical_ids[]= compa.sequence.get(0);
				
				 session.put(SESSION_LEFT_RESULTS, organized.get(vertical_ids[0]));
				 session.put(SESSION_RIGHT_RESULTS, organized.get(vertical_ids[1]));
				 
				 
				 start_time = new Date();
				 session.put(START_TIME, start_time);
				 
				 
			 }
			 
			
		}
	
		
	}

	
}
